﻿#include <QString>
#include <glog/logging.h>

#include "util/utils.h"
#include "manager/config_manager.h"
#include "manager/calibrate_manager.h"

CalibrateManager::CalibrateManager() {}

CalibrateManager::~CalibrateManager() {}

CalibrateManager *CalibrateManager::get_instance() {
    static CalibrateManager instance;
    return &instance;
}

bool CalibrateManager::init(std::vector<cv::Point2f> *src,
    std::vector<cv::Point2f> *dst) {
    LOG(INFO) << "CalibrateManager | init";
    m_trans_mtx = cv::getPerspectiveTransform(*src, *dst);
    return true;
}

// 重新初始化转换矩阵
bool CalibrateManager::reinit(CalibrateEntity calibrate) {
    std::vector<cv::Point2f> src, dst;
    cv::Point2f point;
    // 构造原图坐标点
    for (int i = 0; i < CALIBRATE_POINT_COUNT; ++i) {
        point.x = calibrate.target_points[i].x();
        point.y = calibrate.target_points[i].y();
        src.push_back(point);
    }
    // 构造透视图坐标点
    for (int i = 0; i < CALIBRATE_POINT_COUNT; ++i) {
        point.x = calibrate.prespective_points[i].x();
        point.y = calibrate.prespective_points[i].y();
        dst.push_back(point);
    }
    // 重新初始化
    init(&src, &dst);
    // 转换为配置字符串
    QString str_target_point = Utils::get_points_str(src);
    QString str_prespective_point = Utils::get_points_str(dst);
    // 更新配置文件
    ConfigEntity *config = ConfigManager::getInstance()->get_ecb_config();
    config->target_points = str_target_point;
    config->prespective_points = str_prespective_point;
    LOG(INFO) << "CalibrateManager | reinit| target_points" << config->target_points.toStdString();
    LOG(INFO) << "CalibrateManager | reinit| prespective_points" << config->prespective_points.toStdString();
    // 保存配置
    ConfigManager::getInstance()->save();
    return true;
}

QSharedPointer<cv::Mat> CalibrateManager::wrap_perspective(cv::Mat *src) {
    LOG(INFO) << "CalibrateManager | wrap_perspective";
    QSharedPointer<cv::Mat> sp_dst(new cv::Mat());
    cv::warpPerspective(*src, *sp_dst, m_trans_mtx, src->size(), cv::INTER_LINEAR);
    return sp_dst;
}

std::vector<cv::Point2f> CalibrateManager::get_trans_ponits(
    std::vector<cv::Point2f> *v_points) {
    // LOG(INFO) << "CalibrateManager | get_trans_ponits";
    std::vector<cv::Point2f> points_trans;
    cv::perspectiveTransform(*v_points, points_trans, m_trans_mtx);
    return points_trans;
}
